package com.app.config;


import com.app.service.CustomUserDetailsService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.config.http.SessionCreationPolicy;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.security.web.SecurityFilterChain;
import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter;


/**
 * @Author: cn
 * @Description: Spring Security 配置类
 *              包括安全过滤链、密码编码器、用户详情服务等配置
 * @Date: 2025/7/12 11:08
 * @Version: 1.0
 */
@Configuration
@EnableWebSecurity
public class SecurityConfig {
    @Autowired
    private CustomUserDetailsService customUserDetailsService; // 注入自定义的 UserDetailsService 实现

    @Autowired
    private JwtRequestFilter jwtRequestFilter; // 注入 JWT 拦截器

    /**
     * 配置 HTTP 安全策略
     * - URL 访问权限控制
     * - 登录方式配置（表单登录 + HTTP Basic）
     * - 不使用 CSRF（适用于前后端分离或 API 场景）
     *
     * @param http HttpSecurity 对象
     * @return SecurityFilterChain
     * @throws Exception 异常
     */
    @Bean
    public SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception {
        http
                .csrf().disable()
                .sessionManagement()
                .sessionCreationPolicy(SessionCreationPolicy.STATELESS)
                .and()
                .addFilterBefore(jwtRequestFilter, UsernamePasswordAuthenticationFilter.class)
                .authorizeRequests()
                // 只有登录接口放行
                .antMatchers("/api/auth/login").permitAll()
                // 其他所有请求都需要认证
                .anyRequest().authenticated()
                .and()
                .formLogin().disable()  // 禁用 formLogin，因为我们使用 JWT
                .logout().disable();    // 同样禁用 logout，因为无状态
        return http.build();
    }

    /**
     * 密码编码器 Bean
     * 使用 BCrypt 算法对密码进行哈希加密
     *
     * @return PasswordEncoder 实例
     */
    @Bean
    public PasswordEncoder passwordEncoder() {
        return new BCryptPasswordEncoder();
    }

    // 暴露 AuthenticationManager 为 Bean
    @Bean
    public AuthenticationManager authenticationManager(HttpSecurity http) throws Exception {
        return http.getSharedObject(AuthenticationManagerBuilder.class)
                .userDetailsService(customUserDetailsService)
                .passwordEncoder(passwordEncoder())
                .and()
                .build();
    }
}
